package com.laf.manage.listener;

import cn.hutool.core.bean.BeanUtil;
import com.laf.common.constant.Constants;
import com.laf.common.constant.MQConstant;
import com.laf.common.exception.ServiceException;
import com.laf.common.utils.image.GrayscaleUtils;
import com.laf.manage.constant.LostItemStatusConstant;
import com.laf.manage.domain.doc.LostItemDoc;
import com.laf.manage.domain.dto.AddItemDocMsg;
import com.laf.manage.domain.dto.GrayscaleDTO;
import com.laf.manage.domain.po.Category;
import com.laf.manage.domain.po.LostItem;
import com.laf.manage.mapper.es.LostItemEsMapper;
import com.laf.manage.service.ICategoryService;
import com.laf.manage.service.ILostItemService;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class LostItemListener {

    @Autowired
    private ILostItemService lostItemService;

    @Autowired
    private LostItemEsMapper lostItemEsMapper;

    @Autowired
    private ICategoryService categoryService;


    /**
     * 处理mysql to es 写的lostItem 消息
     *
     * @param msg id: 物品Id
     *            status：物品状态
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(
                    value = MQConstant.LOST_ITEM_ADD_QUEUE,
                    durable = "true",
                    arguments = @Argument(name = "x-queue-mode", value = "lazy") // 懒加载，减少内存消耗
            ),
            exchange = @Exchange(MQConstant.LOST_ITEM_EXCHANGE),
            key = MQConstant.LOST_ITEM_ADD_ROUTING_KEY
    ))
    public void addLostItemToEs(AddItemDocMsg msg) {
        // 校验数据
        Long id = msg.getId();
        LostItem lostItem = lostItemService.getById(id);
        if (lostItem == null) return;

        // 做幂等性处理
        LostItemDoc itemDoc = lostItemEsMapper.selectById(id);
        if (itemDoc != null) return;

        // 2. 写入es
        LostItemDoc doc = BeanUtil.toBean(lostItem, LostItemDoc.class);
        List<String> itemUrls = lostItem.getItemUrls();
        if (itemUrls != null && !itemUrls.isEmpty()) {
            doc.setItemUrl(itemUrls.get(0));
        }
        List<String> showUrls = lostItem.getShowUrls();
        if (showUrls != null && !showUrls.isEmpty()) {
            doc.setShowUrl(showUrls.get(0));
        }
        if (msg.getStatus() != null) {
            doc.setStatus(msg.getStatus());
        }
        Integer result = lostItemEsMapper.insert(doc);
        if (result <= 0) throw new ServiceException(" LostItemListener.addLostItemToEs 写入es 失败 ，id: " + id);

        // 如果是待领取状态，就生成灰度图
        if (msg.getStatus().equals(LostItemStatusConstant.WAIT_PICKED)){
            GrayscaleDTO grayscaleDTO = new GrayscaleDTO();
            grayscaleDTO.setId(id);
            Category category = categoryService.getById(doc.getCategoryId());
            grayscaleDTO.setIsGrayscale(Constants.DEFAULT_IMAGE_VAL.equals(category.getIsDefaultImage()));
            generateGrayImage(grayscaleDTO );
        }

    }


    /**
     * 为已经提交的物品生成灰度图，更新到 mysql 和 es 中
     *
     * @Param id 失物id
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(
                    value = MQConstant.LOST_ITEM_GRAYSCALE_GENERATION_QUEUE,
                    durable = "true", // 持久化队列
                    arguments = @Argument(name = "x-queue-mode", value = "lazy")
            ),
            exchange = @Exchange(MQConstant.LOST_ITEM_EXCHANGE),
            key = MQConstant.LOST_ITEM_GRAYSCALE_GENERATION_ROUTING_KEY
    ))
    public void generateGrayImage(GrayscaleDTO dto) {
        // 1. 检查 mysql 中是否存在
        LostItem lostItem = lostItemService.getById(dto.getId());
        if (lostItem == null) return;

        // 2.给失物生成对应灰度图
        List<String> itemUrls = lostItem.getItemUrls();
        List<String> showUrls = new ArrayList<>();
        if (itemUrls == null || itemUrls.isEmpty()) return;
        if (dto.getIsGrayscale()) {
            showUrls = GrayscaleUtils.generateGrayscale(itemUrls);
        } else {
            // 使用默认图片
            for (int i = 0; i < itemUrls.size(); i++) {
                showUrls.add(Constants.DEFAULT_IMAGE);
            }
        }
        lostItem.setShowUrls(showUrls);

        // 3.更新showUrl 字段
        lostItemService.updateById(lostItem);

        // 处理 es 中的数据
        LostItemDoc lostItemDoc = lostItemEsMapper.selectById(dto.getId());
        // 3.1 如果不存在，就新增
        if (lostItemDoc == null) {
            LostItemDoc insertDoc = BeanUtil.copyProperties(lostItem, LostItemDoc.class);
            insertDoc.setItemUrl(itemUrls.get(0));
            insertDoc.setShowUrl(showUrls.get(0));
            lostItemEsMapper.insert(insertDoc);
        } else {
            // 更新 showUrl 字段 ， 只需要获取 第一张图片的灰度图即可
            lostItemDoc.setShowUrl(showUrls.get(0));
            lostItemEsMapper.updateById(lostItemDoc);
        }
    }

}
